﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Net;
using System.Net.Sockets;
using System.Net.NetworkInformation;
using System.Text.RegularExpressions;
using NetService.Define;

namespace NetService
{
    public partial class MainForm : Form
    {
        public MainForm()
        {
            InitializeComponent();
        }

        /*
         * \brief 获取本地计算机当前全部网络信息
         */
        List<IPData> IPDataList = new List<IPData>();

        /*
         * \brief 获取本地全部网卡信息
         * 
         * \param  sender  获取响应物体
         * \param  e 响应事件
         */
        private void MainForm_Load(object sender, EventArgs e)
        {
            Dictionary<string, List<string>> adapterDataGroupDic = new Dictionary<string, List<string>>();
            List<string> tempList = new List<string>();
            string adapterName = String.Empty;

            // 获取主机名称
            PCNameTb.Text = Dns.GetHostName();
            // IP列表数据
            IPDataList.Clear();

            string[] configList = GetIPConfigByCmd().Split('\n');

            for (int i = 0; i < configList.Length; i++)
            {
                if (!String.IsNullOrWhiteSpace(configList[i]) && !configList[i].StartsWith(" ") && !configList[i].Contains("Windows"))
                {
                     List<string> temp2List = new List<string>();
                     if (0 != tempList.Count && !adapterDataGroupDic.ContainsKey(configList[i]))
                     {
                         temp2List.AddRange(tempList);
                         adapterDataGroupDic.Add(adapterName, temp2List);
                     }
                     adapterName = configList[i].Split(':')[0].Trim();
                     tempList.Clear();
                }
                else if (!String.IsNullOrWhiteSpace(adapterName) && !String.IsNullOrWhiteSpace(configList[i])) 
                {
                    tempList.Add(configList[i]);
                }
            }

            foreach (var adapterDataList in adapterDataGroupDic) 
            {
                IPData ipData = new IPData();
                ipData.Name = adapterDataList.Key;
                DNSAddressData dnsData = new DNSAddressData();
                // 网卡信息收集
                NetworkCardsCb.Items.Add(adapterDataList.Key);
                foreach (var v in adapterDataList.Value) 
                {
                    if (v.Contains("IPv4"))
                    {
                        // IPv4信息收集
                        if (!String.IsNullOrWhiteSpace(v.Split(':')[1]))
                        {                           
                            dnsData.IPAddress = v.Split(':')[1].Trim();
                        }
                    }
                    if (v.Contains("子网掩码"))
                    {
                        // 子网掩码信息收集
                        if (!String.IsNullOrWhiteSpace(v.Split(':')[1]))
                        {
                            dnsData.SubNetMaskAddress = v.Split(':')[1].Trim();
                        }
                    }
                    if (v.Contains("默认网关"))
                    {
                        // 默认网关信息收集
                        if (!String.IsNullOrWhiteSpace(v.Split(':')[1]))
                        {
                            dnsData.GateWayAddress = v.Split(':')[1].Trim();
                        }
                    }
                }
                ipData.DNSAddressDataList.Add(dnsData);
                IPDataList.Add(ipData);
            }

            // 初始化数据
            if (0 != NetworkCardsCb.Items.Count)
            {
                NetworkCardsCb.Text = IPDataList[0].Name;
                IPAddressCb.Text = IPDataList[0].DNSAddressDataList[0].IPAddress;
                SubNetMaskAddressCb.Text = IPDataList[0].DNSAddressDataList[0].SubNetMaskAddress;
                GateWayAddressCb.Text = IPDataList[0].DNSAddressDataList[0].GateWayAddress;
            }
        }

        /*
         * \brief 获取IPCONFIG返回值
         * 
         * \return  data 返回 IPCONFIG输出
         */
        public static string GetIPConfigByCmd()
        {
            string data = String.Empty;
            string version = System.Environment.OSVersion.VersionString;
            if (version.Contains("Windows"))
            {
                System.Diagnostics.ProcessStartInfo psi = new System.Diagnostics.ProcessStartInfo("ipconfig", "/all"); //调用ipconfig ,并传入参数: /all 
                psi.CreateNoWindow = true; //若为false，则会出现cmd的黑窗体
                psi.RedirectStandardOutput = true;
                psi.UseShellExecute = false;

                System.Diagnostics.Process p = System.Diagnostics.Process.Start(psi);
                data = p.StandardOutput.ReadToEnd();
            }
            return data;
        }

        /*
         * \brief 获取IP数据
         * 
         * \return  data 返回 IPCONFIG输出
         */
        public  void GetIPData()
        {

            // 获取说有网卡信息
            NetworkInterface[] nics = NetworkInterface.GetAllNetworkInterfaces();
            foreach (var adapter in nics)
            {
                //网关地址
                string strGateway = String.Empty;
                //if (adapter.NetworkInterfaceType == NetworkInterfaceType.Wireless80211)
                //{

                IPData ipData = new IPData();
                DNSAddressData dnsData = new DNSAddressData();
                ipData.Name = adapter.Description;
                NetworkCardsCb.Items.Add(adapter.Description);
                //网卡Mac地址
                System.Net.NetworkInformation.PhysicalAddress mac = adapter.GetPhysicalAddress();
                //TODO:根据mac 地址 匹配目标网卡

                // 单个网卡的IP对象
                IPInterfaceProperties ipProperties = adapter.GetIPProperties();
                // 获取单播地址集
                IPAddressCollection ipCollection = ipProperties.DnsAddresses;
                foreach (IPAddress ipadd in ipCollection)
                {
                    //InterNetwork    IPV4地址      InterNetworkV6        IPV6地址 Max            MAX 位址
                    //if (ipadd.Address.AddressFamily == AddressFamily.InterNetwork)
                    //{
                    // 判断是否为ipv4并获取ip
                    NetworkCardsCb.Text = ipadd.ToString();
                    dnsData.IPAddress = ipadd.ToString();
                    ipData.DNSAddressDataList.Add(dnsData);
                    //}
                }

                //获取该IP对象的网关
                GatewayIPAddressInformationCollection gateways = ipProperties.GatewayAddresses;
                foreach (var gateWay in gateways)
                {
                    //如果能够Ping通网关
                    if (IsPingIP(gateWay.Address.ToString()))
                    {
                        //得到网关地址
                        strGateway = gateWay.Address.ToString();
                        //跳出循环
                        break;
                    }
                }
                //如果已经得到网关地址
                if (strGateway.Length > 0)
                {
                    string[] gatewayList = strGateway.Split(new string[] { "." }, StringSplitOptions.RemoveEmptyEntries);
                    for (int i = 0; i < ipData.DNSAddressDataList.Count; i++)
                    {
                        bool vaild = true;
                        string[] IPAddressList = ipData.DNSAddressDataList[i].IPAddress.Split(new string[] { "." }, StringSplitOptions.RemoveEmptyEntries);
                        for (int j = 0; j < 3; j++)
                        {
                            if (IPAddressList[j] != gatewayList[j])
                            {
                                vaild = false;
                                break;
                            }
                        }
                        // 
                        if (vaild)
                        {
                            ipData.DNSAddressDataList[i].GateWayAddress = strGateway;
                        }
                    }
                    //跳出循环
                    break;
                }
                // IP数据列表收集
                IPDataList.Add(ipData);
                //}
            }
        }

        /*
         * \brief 获取本地主机IP内容
         * 
         * \param  sender  获取响应物体
         * \param  e 响应事件
         */
        private void FindPCIPBn_Click(object sender, EventArgs e)
        {
            string name = Dns.GetHostName();
            IPAddress[] ipads = Dns.GetHostAddresses(name);
            foreach(IPAddress ip in ipads)
            {
                if (ip.AddressFamily == AddressFamily.InterNetwork)
                {
                    IPAddressCb.Items.Add(ip.ToString());
                }
            }
            IPAddressCb.Text = IPAddressCb.Items[0].ToString();
        }

        /*
         * \brief 获取对应网址内容
         * 
         * \param  sender  获取响应物体
         * \param  e 响应事件
         */
        private void ScanIPBn_Click(object sender, EventArgs e)
        {
            if (IPAddressCb.Text.Split(new string[] { "." }, StringSplitOptions.RemoveEmptyEntries).Count() < 4) {
                MessageBox.Show("请获取本地ip后再扫描");
                return;
            }
            for (int i = 0; i < 255; i++)
            {
                Ping p;
                p = new Ping();
                p.PingCompleted +=new PingCompletedEventHandler(p_PingCompleted);

                //string pip = "120.40.53." + i.ToString();
                string pip = string.Join(".", IPAddressCb.Text.Split(new string[] { "." }, StringSplitOptions.RemoveEmptyEntries).Take(3).ToArray()) + "." + i.ToString();
                p.SendAsync(pip,2000,null);
            }
        }

        /*
         * \brief 获取对应DNS数据
         * 
         * \param  sender  获取响应物体
         * \param  e 响应事件
         */
        private void ScanDnsData_Click(object sender, EventArgs e)
        {
            //判断是否输入了主机地址
            if (DnsIPTb.Text == string.Empty)
            {
                MessageBox.Show("请输入主机地址!");
            }
            else
            {
                //获取指定主机的IP地址
                IPAddress[] ips = Dns.GetHostAddresses(DnsIPTb.Text);
                //循环访问获得的IP地址
                foreach (IPAddress ip in ips)
                {
                    textBox2.Text = ip.ToString();//将得到的IP地址显示在文本框中
                }
                //根据指定的主机名获取DNS信息
                textBox4.Text = Dns.GetHostByName(Dns.GetHostName()).HostName;
            }
        }


        private void p_PingCompleted(object sender,PingCompletedEventArgs e)
        {
               if(e.Reply.Status==IPStatus.Success)
               {
                   listBox1.Items.Add(e.Reply.Address.ToString());
                   try
                   {
                       string[] IPAddressList = e.Reply.Address.ToString().Split(new string[] { "." }, StringSplitOptions.RemoveEmptyEntries);
                       if (IPAddressList[3] != "1")
                       {
                           IPHostEntry ipAddress = Dns.GetHostByAddress(e.Reply.Address);
                           listBox1.Items.Add(ipAddress.HostName);
                       }
                   }
                   catch { }
               }
        }

        /*
         * \brief 获取当前选择网卡信息
         * 
         * \param  sender  获取响应物体
         * \param  e 响应事件
         */
        private void NetworkCardsCb_SelectedIndexChanged(object sender, EventArgs e)
        {
            IPAddressCb.Items.Clear();
            foreach (var v in IPDataList)
            {
                if (NetworkCardsCb.Text == v.Name)
                {
                    IPAddressCb.Items.Clear();
                    SubNetMaskAddressCb.Items.Clear();
                    GateWayAddressCb.Items.Clear();
                    foreach (var w in v.DNSAddressDataList)
                    {
                        IPAddressCb.Items.Add(w.IPAddress);
                        SubNetMaskAddressCb.Items.Add(w.SubNetMaskAddress);
                        GateWayAddressCb.Items.Add(w.GateWayAddress);
                    }
                    IPAddressCb.Text = IPAddressCb.Items[0].ToString();
                    SubNetMaskAddressCb.Text = SubNetMaskAddressCb.Items[0].ToString();
                    GateWayAddressCb.Text = GateWayAddressCb.Items[0].ToString();
                }
            }
        }

        /**
         * \brief TCP/IP测试界面
         *
         * \param  sender  获取响应物体
         * \param  e 响应事件
         */
        private void TCPIPConnectBn_Click(object sender, EventArgs e)
        {
            TcpUdpMessageForm tcpTestForm = new TcpUdpMessageForm();
            tcpTestForm.Show();
        }

        /**
         * \brief Socket测试界面
         *
         * \param sender  获取响应物体
         * \param e 响应事件
         */
        private void SocketConnectBn_Click(object sender, EventArgs e)
        {
            SocketForm socketTestForm = new SocketForm();
            socketTestForm.Show();
        }

     /**
       * \brief 得到本机IP
       */
      private string GetLocalIP()
      {
          //本机IP地址
          string strLocalIP = String.Empty;
          //得到计算机名
          string strPcName = Dns.GetHostName();
          //得到本机IP地址数组
          IPHostEntry ipEntry = Dns.GetHostEntry(strPcName);
          //遍历数组
          foreach (var IPadd in ipEntry.AddressList)
          {
              //判断当前字符串是否为正确IP地址
              if (IsRightIP(IPadd.ToString()))
             {
                  //得到本地IP地址
                  strLocalIP = IPadd.ToString();
                  //结束循环
                  break;
              }
          }
          //返回本地IP地址
          return strLocalIP;
      }

      /**
        * \brief 判断是否为正确的IP地址
        *
        * \param strIPadd 需要判断的字符串
        * \return vaild 判断是否是正确IP
        */
        public static bool IsRightIP(string strIPadd)
        {
            bool vaild = false;
            //利用正则表达式判断字符串是否符合IPv4格式
            if (Regex.IsMatch(strIPadd, "[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}"))
            {
                //根据小数点分拆字符串
                string[] ips = strIPadd.Split('.');
                if (ips.Length == 4 || ips.Length == 6)
                {
                    //如果符合IPv4规则
                    if (System.Int32.Parse(ips[0]) < 256 && System.Int32.Parse(ips[1]) < 256 & System.Int32.Parse(ips[2]) < 256 & System.Int32.Parse(ips[3]) < 256)
                    {
                        vaild =  true;
                    }
                    else
                    { }
                }
                else
                { }
            }
            else
            { }
             return vaild;
        }

        /**
         * \brief 得到网关地址
         */
        private string GetGateway()
        {
            //网关地址
            string strGateway = "";
            //获取所有网卡
            NetworkInterface[] nics = NetworkInterface.GetAllNetworkInterfaces();
            //遍历数组
            foreach (var netWork in nics)
            {
                //单个网卡的IP对象
                IPInterfaceProperties ip = netWork.GetIPProperties();
                //获取该IP对象的网关
                GatewayIPAddressInformationCollection gateways = ip.GatewayAddresses;
                foreach (var gateWay in gateways)
                {
                    //如果能够Ping通网关
                    if (IsPingIP(gateWay.Address.ToString()))
                    {
                        //得到网关地址
                        strGateway = gateWay.Address.ToString();
                        //跳出循环
                        break;
                    }
                }
                //如果已经得到网关地址
                if (strGateway.Length > 0)
                {
                    //跳出循环
                    break;
                }
            }
            //返回网关地址
            return strGateway;
        }

        /**
         * \brief 尝试Ping指定IP是否能够Ping通
         * 
         * \param strIP 指定IP
         * \return vaild 判断是否为ping通的IP
         */
        public static bool IsPingIP(string strIP)
        {
            try
            {
                //创建Ping对象
                Ping ping = new Ping();
                //接受Ping返回值
                PingReply reply = ping.Send(strIP, 1000);
                //Ping通
                return true;
            }
            catch
            {
                //Ping失败
                return false;
            }
        }
    }
}
